package profileEditor;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import GUIMain.GUIFocusManager;
import GUIMain.ProfileEditorGUI;

import data.ProfileList;
import data.Reference;
import data.TopOceanInfo;
import employeeOperations.SelectEmployeeDialog;

import storage.FieldInfo;
import storage.Profile;
import storage.Rule;
import storage.RuleGroup;

public class ProfileEditor {

	private static String profileName;
	//Company Info
	private static String cnee 					="";
	private static String street				="";
	private static String state					="";
	private static String city					="";
	private static String zip					="";
	private static String country				="";
	private static String telephone				="";
	private static String email					="";
	private static String contact				="";
	private static String type					="";
	//Topocean Info
	private static HashMap<String,ArrayList<String>> originEmployeeMap;
	private static HashMap<String,ArrayList<String>> destEmployeeMap;
	private static String saleHandler			="";
	//Billing 
	private static double chargePerContainer	=0.0;
	private static int term						=0;
	private static String daysAfter				="";
	private static String billTo				="";
	private static String companyType			="";
	
	//Display Variables
	public static JDialog panel;
	private static JPanel infoPanel;
	private static JPanel rulePanel;
	private static JLabel profileNameLabel;
	private static JTextField profileNameText;
	private static JPanel companyInfoPanel;
	private static JLabel cneeLabel;
	private static JTextField cneeText;
	private static JPanel addressPanel;
	private static JLabel streetLabel;
	private static JTextField streetText;
	private static JLabel cityLabel;
	private static JTextField cityText;
	private static JLabel stateLabel;
	private static JTextField stateText;
	private static JLabel zipLabel;
	private static JTextField zipText;
	private static JLabel countryLabel;
	private static JComboBox countryCombo;
	private static JLabel telephoneLabel;
	private static JTextField telephoneText;
	private static JLabel emailLabel;
	private static JTextField emailText;
	private static JLabel contactLabel;
	private static JTextField contactText;
	private static JLabel typeLabel;
	private static JComboBox typeCombo;
	private static JPanel topoInfoPanel;
	private static JLabel originCSCount;
	private static JButton originCSSelector;
	private static JLabel destCSCount;
	private static JButton destCSSelector;
	private static JLabel saleLabel;
	private static JComboBox saleCombo;
	private static JPanel billingPanel;
	private static JLabel chargeLabel;
	private static JTextField chargeText;
	private static JLabel termDayLabel;
	private static JTextField termDayText;
	private static JLabel termFieldLabel;
	private static JComboBox termFieldCombo;
	private static JLabel billToLabel;
	private static JTextField billToText;
	private static GridBagConstraints gbc;
	private static JPanel buttonPanel;
	private static JButton cancel;
	private static JButton submit;
	private static JButton deleteProfile;
	//rule panel
	private static JPanel internalRulePanel;
	private static JScrollPane scrollPane;
	private static ArrayList<Rule> ruleList;
	private static boolean disableListener = false;
	//rule storage NOT THE SAME AS rule panel
	private static Hashtable<String, ArrayList<Rule>> ruleStorageList;
	private static Hashtable<String, Boolean> ruleActiveList;
	private static Profile profileReference;
	/**
	 * Opens a new editor based on an existing profile
	 * @param profile of a cnee to be edited
	 */
	@SuppressWarnings("unchecked")
	public static void openEditor(Profile profile){
		deleteProfile.setText("Delete Profile"); //Allows a user to select a previously made profile to copy from
		//assign profile data to fields
		cnee = profile.cnee;
		street = profile.street;
		city = profile.city;
		state = profile.state;
		zip = profile.zip;
		country = profile.country;
		profileName = profile.profileName;
		telephone = profile.telephone;
		email = profile.email;
		contact = profile.contact;
		originEmployeeMap = ProfileList.cleanEmployeeList((HashMap<String,ArrayList<String>>) profile.originEmployeeMap,true);	
		originCSCount.setText(Integer.toString(countEmployees(originEmployeeMap)));
		destEmployeeMap = ProfileList.cleanEmployeeList((HashMap<String,ArrayList<String>>) profile.destEmployeeMap,false);
		destCSCount.setText(Integer.toString(countEmployees(destEmployeeMap)));
		saleHandler = profile.saleHandler;
		chargePerContainer = profile.chargePerContainer;
		term = profile.term;
		daysAfter = profile.daysAfter;
		billTo = profile.billTo;
		ruleStorageList = (Hashtable<String, ArrayList<Rule>>) profile.ruleList.clone();
		ruleActiveList = new Hashtable<String, Boolean>();
		
		disableListener = true;
		for(int i=0;i<ruleList.size();i++){
			try{
				ruleActiveList.put(ruleList.get(i).field, profile.ruleList.get(ruleList.get(i).field).get(0).active);
			}catch(NullPointerException e){
			}
			profileReference = profile;
			if(profile.ruleList.containsKey(ruleList.get(i).field)&&
					profile.ruleList.get(ruleList.get(i).field).size()>0){
				//Profile contains a rule for this field 
				ruleList.get(i).checkBox.setEnabled(true);
				ruleList.get(i).checkBox.setSelected(profile.ruleList.get(ruleList.get(i).field).get(0).active);
			}else{
				ruleList.get(i).checkBox.setEnabled(false);
				ruleList.get(i).checkBox.setSelected(false);
			}
		}
		disableListener = false;
		display();
		profileNameText.setEditable(false);
	}
	/**
	 * Opens a blank editor to add a new profile
	 */
	public static void openEditor(){
		deleteProfile.setText("Duplicate Profile"); //Allows a user to select a previously made profile to copy from
		//deleteProfile.setEnabled(false); //Disable profile deletion for profiles that do not exist
		profileName 		="";
		cnee 				="";
		street				="";
		city				="";
		state				="";
		zip					="";
		country				="";
		telephone			="";
		email				="";
		contact				="";
		type				="";
		//Topocean Info
		originEmployeeMap	= new HashMap<String,ArrayList<String>>();
		destEmployeeMap		= new HashMap<String,ArrayList<String>>();
		saleHandler			="";
		//Billing 
		chargePerContainer	=0.0;
		term				=0;
		daysAfter			="ETA";
		billTo				="";
		companyType			="";
		display();
		profileNameText.setEditable(true);
		ruleStorageList = null;
		ruleStorageList = new Hashtable<String, ArrayList<Rule>>();
		ruleActiveList = new Hashtable<String, Boolean>();
		profileReference	= null;
		disableListener = true;
		for(int i=0;i<ruleList.size();i++){
			ruleList.get(i).checkBox.setEnabled(false);
			ruleList.get(i).checkBox.setSelected(false);
		}
		disableListener = false;
	}
	/**
	 * Shows the GUI to the user
	 */
	private static void display(){
		//Set all fields in the display to the local values
		profileNameText.setText(profileName);
		cneeText.setText(cnee);
		streetText.setText(street);
		cityText.setText(city);
		stateText.setText(state);
		zipText.setText(zip);
		countryCombo.setSelectedItem(country);
		telephoneText.setText(telephone);
		emailText.setText(email);
		contactText.setText(contact);
		typeCombo.setSelectedItem(type);
		

		disableListener = true;
		//Refresh data in combo box lists
		/*
		 * TODO Add CS initialization functions
		 */
		
		saleCombo.setSelectedItem(saleHandler);
		chargeText.setText(Double.toString(chargePerContainer));
		termDayText.setText(Integer.toString(term));
		termFieldCombo.setSelectedItem(daysAfter);
		billToText.setText(billTo);

		GUIFocusManager.add(panel);
	}
	public static void initialize(){
		panel = new JDialog();
		panel.setTitle("Profile Editor");
		panel.setResizable(false);
		infoPanel = new JPanel();
		rulePanel = new JPanel();
		profileNameLabel = new JLabel("Profile Name");
		profileNameText = new JTextField();
		profileNameText.setPreferredSize(new Dimension(200,25));
		companyInfoPanel = new JPanel();
		cneeLabel = new JLabel("CNEE");
		cneeText = new JTextField();
		cneeText.setPreferredSize(new Dimension(200,25));
		addressPanel = new JPanel();
		streetLabel = new JLabel("Street");
		streetText = new JTextField();
		streetText.setPreferredSize(new Dimension(250,25));
		cityLabel = new JLabel("City");
		cityText = new JTextField();
		cityText.setPreferredSize(new Dimension(140,25));
		stateLabel = new JLabel("State");
		stateText = new JTextField();
		stateText.setPreferredSize(new Dimension(75,25));
		zipLabel = new JLabel(" Zip");
		zipText = new JTextField();
		zipText.setPreferredSize(new Dimension(50,25));
		countryLabel = new JLabel("Country");
		countryCombo = new JComboBox(Reference.countryList.toArray()); // edit
		countryCombo.setPreferredSize(new Dimension(150,25));
		telephoneLabel = new JLabel("Telephone");
		telephoneText = new JTextField();
		telephoneText.setPreferredSize(new Dimension(200,25));
		emailLabel = new JLabel("Email");
		emailText = new JTextField();
		emailText.setPreferredSize(new Dimension(200,25));
		contactLabel = new JLabel("Contact");
		contactText = new JTextField();
		contactText.setPreferredSize(new Dimension(200,25));
		typeLabel = new JLabel("Company Type");
		typeCombo = new JComboBox(TopOceanInfo.companyTypes.toArray());
		typeCombo.setPreferredSize(new Dimension(200,25));
		topoInfoPanel = new JPanel();
		originCSCount = new JLabel("0");
		originCSSelector = new JButton("Select Origin CS");
		originCSSelector.setPreferredSize(new Dimension(150,25));
		destCSCount = new JLabel("0");
		destCSSelector = new JButton("Select Dest CS");
		destCSSelector.setPreferredSize(new Dimension(150,25));

		saleLabel = new JLabel("Sales Member");
		saleCombo = new JComboBox(TopOceanInfo.salesHandler.toArray());
		saleCombo.setPreferredSize(new Dimension(150,25));
		billingPanel = new JPanel();
		chargeLabel = new JLabel("Charge Per Container");
		chargeText = new JTextField();
		chargeText.setPreferredSize(new Dimension(200,25));
		termDayLabel = new JLabel("Term");
		termDayText = new JTextField();
		termDayText.setPreferredSize(new Dimension(200,25));
		termFieldLabel = new JLabel("Days After");
		updateFields();
		termFieldCombo.setPreferredSize(new Dimension(200,25));
		billToLabel = new JLabel("Bill To");
		billToText = new JTextField();
		billToText.setPreferredSize(new Dimension(200,25));
		buttonPanel = new JPanel();
		buttonPanel.setLayout(new GridBagLayout());
		ruleStorageList = new Hashtable<String, ArrayList<Rule>>();
		cancel = new JButton("Cancel");
		submit = new JButton("Submit");
		deleteProfile = new JButton("Delete Profile");
		gbc = new GridBagConstraints();
		
		panel.setLayout(new GridBagLayout());
		infoPanel.setLayout(new GridBagLayout());
		//infoPanel.setPreferredSize(new Dimension(410,966));
		rulePanel.setLayout(new GridBagLayout());
		
		companyInfoPanel.setLayout(new GridBagLayout());
		companyInfoPanel.setBorder(BorderFactory.createTitledBorder("Company Info"));

		addressPanel.setLayout(new GridBagLayout());
		addressPanel.setBorder(BorderFactory.createTitledBorder("Address"));
		
		topoInfoPanel.setLayout(new GridBagLayout());
		topoInfoPanel.setBorder(BorderFactory.createTitledBorder("TopOcean Info"));
		
		billingPanel.setLayout(new GridBagLayout());
		billingPanel.setBorder(BorderFactory.createTitledBorder("Billing Info"));
				
		gbc.insets.top = 3;
		gbc.insets.left = 3;
		gbc.insets.bottom = 3;
		gbc.insets.right = 3;
		
		gbc.gridheight = 1;
		gbc.gridwidth  = 1;
		
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		infoPanel.add(profileNameLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 0;
		infoPanel.add(profileNameText,gbc);
		
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		companyInfoPanel.add(cneeLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 0;
		companyInfoPanel.add(cneeText,gbc);
		
		
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		addressPanel.add(streetLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 0;
		addressPanel.add(streetText,gbc);
		
		JPanel cityStatePanel = new JPanel();
		cityStatePanel.setLayout(new GridBagLayout());
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		cityStatePanel.add(cityLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 0;
		cityStatePanel.add(cityText,gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 2;
		gbc.gridy = 0;
		cityStatePanel.add(stateLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 3;
		gbc.gridy = 0;
		cityStatePanel.add(stateText,gbc);
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 1;
		addressPanel.add(cityStatePanel,gbc);
		
		gbc.gridwidth = 1;
		JPanel zipCountryPanel = new JPanel();
		zipCountryPanel.setLayout(new GridBagLayout());
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		zipCountryPanel.add(zipLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 0;
		zipCountryPanel.add(zipText,gbc);
		gbc.gridwidth = 1;
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 2;
		gbc.gridy = 0;
		zipCountryPanel.add(countryLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 3;
		gbc.gridy = 0;
		zipCountryPanel.add(countryCombo,gbc);
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 2;
		addressPanel.add(zipCountryPanel,gbc);
		
		
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 0;
		gbc.gridy = 1;
		gbc.gridwidth = 2;
		gbc.gridheight = 5;
		addressPanel.setPreferredSize(new Dimension(350,150));
		companyInfoPanel.add(addressPanel,gbc);
		
		
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 7;
		companyInfoPanel.add(telephoneLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 7;
		companyInfoPanel.add(telephoneText,gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 8;
		companyInfoPanel.add(emailLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 8;
		companyInfoPanel.add(emailText,gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 9;
		companyInfoPanel.add(contactLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 9;
		companyInfoPanel.add(contactText,gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 10;
		companyInfoPanel.add(typeLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 1;
		gbc.gridy = 10;
		companyInfoPanel.add(typeCombo,gbc);
		
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 1;
		companyInfoPanel.setPreferredSize(new Dimension(400, 310));
		infoPanel.add(companyInfoPanel,gbc);
		
		//Add topo info
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridwidth = 1;
		gbc.gridx = 0;
		gbc.gridy = 0;
		topoInfoPanel.add(new JLabel("Number of Employees: "),gbc);
		gbc.gridwidth = 1;
		gbc.gridx = 1;
		gbc.gridy = 0;
		topoInfoPanel.add(originCSCount,gbc);
		JPanel originCSPanel = new JPanel();
		originCSPanel.setLayout(new GridBagLayout());
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		originCSPanel.add(originCSSelector,gbc);
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 1;
		topoInfoPanel.add(originCSPanel,gbc);
		
		gbc.gridwidth = 1;
		gbc.gridx = 0;
		gbc.gridy = 2;
		topoInfoPanel.add(new JLabel("Number of Employees: "),gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridwidth = 1;
		gbc.gridx = 1;
		gbc.gridy = 2;
		topoInfoPanel.add(destCSCount,gbc);
		JPanel destCSPanel = new JPanel();
		destCSPanel.setLayout(new GridBagLayout());
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 0;
		destCSPanel.add(destCSSelector,gbc);
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 3;
		topoInfoPanel.add(destCSPanel,gbc);
		
		gbc.gridwidth = 1;
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 0;
		gbc.gridy = 4;
		topoInfoPanel.add(saleLabel,gbc);
		gbc.anchor = GridBagConstraints.LINE_START;
		gbc.gridx = 1;
		gbc.gridy = 4;
		topoInfoPanel.add(saleCombo,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx =0;
		gbc.gridy =2;
		gbc.gridwidth = 2;
		topoInfoPanel.setPreferredSize(new Dimension(400, 180));
		infoPanel.add(topoInfoPanel,gbc);
		
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridwidth = 1;
		gbc.gridx =0;
		gbc.gridy =0;
		billingPanel.add(chargeLabel, gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx =1;
		gbc.gridy =0;
		billingPanel.add(chargeText,gbc);
		
		JPanel termPanel = new JPanel();
		termPanel.setLayout(new GridBagLayout());
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx =0;
		gbc.gridy =0;
		termPanel.add(termDayLabel, gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		termDayText.setPreferredSize(new Dimension(30,25));
		gbc.gridx =1;
		gbc.gridy =0;
		termPanel.add(termDayText,gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx = 2;
		gbc.gridy = 0;
		termPanel.add(termFieldLabel,gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx = 3;
		gbc.gridy = 0;
		termPanel.add(termFieldCombo,gbc);
		
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 1;
		billingPanel.add(termPanel,gbc);
		
		gbc.gridwidth = 1;
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx =0;
		gbc.gridy =2;
		billingPanel.add(billToLabel, gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx =1;
		gbc.gridy =2;
		billingPanel.add(billToText,gbc);
		gbc.anchor = GridBagConstraints.LINE_END;
		gbc.gridx =0;
		gbc.gridy =3;
		billingPanel.add(typeLabel, gbc);
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridx =1;
		gbc.gridy =3;
		billingPanel.add(typeCombo,gbc);
		
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridwidth = 2;
		gbc.gridx = 0;
		gbc.gridy = 3;
		billingPanel.setPreferredSize(new Dimension(400, 160));
		infoPanel.add(billingPanel,gbc);
				
		gbc.gridwidth = 1;
		gbc.gridx = 0;
		gbc.gridy = 0;
		buttonPanel.add(cancel,gbc);
		gbc.gridwidth = 1;
		gbc.gridx = 1;
		gbc.gridy = 0;
		buttonPanel.add(submit,gbc);
		
		gbc.gridx = 2;
		gbc.gridy = 0;
		buttonPanel.add(deleteProfile,gbc);
		
		gbc.gridheight = 10;
		gbc.gridwidth = 1;
		gbc.gridx = 0;
		gbc.gridy = 0;
		panel.add(infoPanel,gbc);
		
		gbc.gridheight =1;
		initializeRulePanel();

		gbc.anchor = GridBagConstraints.CENTER;
		gbc.gridheight = 9;
		gbc.gridx =1;
		gbc.gridy =0;
		panel.add(rulePanel,gbc);
		
		gbc.gridheight = 1;
		gbc.gridx = 1;
		gbc.gridy = 9;
		panel.add(buttonPanel,gbc);
		
		attachListeners();
		
		GUIFocusManager.setDialogProperties(panel);
	}
	/**
	 * @param origin
	 * @param cs
	 */
	public static void updateCSList(boolean origin, ArrayList<String> cs){
	
	}
	/**
	 * Updates the local ruleListStorage for use later (called by the rule editor submit button)
	 * @param fieldName
	 * @param ruleGroupList
	 */
	public static void updateRuleList(String fieldName, ArrayList<RuleGroup> ruleGroupList){
		//clear all previously set rules
		ruleStorageList.put(fieldName, new ArrayList<Rule>());
		boolean ruleExists = false;
		for(int i=0;i<ruleGroupList.size();i++){
			
			//only add if rule exists
			if(ruleGroupList.get(i).subjectFieldCombo.getSelectedIndex()!=-1){
				ruleExists = true;
				
				Rule rule = new Rule(fieldName);
				rule.connector = (String) ruleGroupList.get(i).connectorCombo.getSelectedItem();
				rule.equality = (String) ruleGroupList.get(i).equalityCombo.getSelectedItem();
				rule.groupNo = (Integer) ruleGroupList.get(i).groupCombo.getSelectedItem();
				rule.subjectField = (String) ruleGroupList.get(i).subjectFieldCombo.getSelectedItem();
				rule.targetField = (String) ruleGroupList.get(i).targetFieldCombo.getSelectedItem();
				rule.value = ruleGroupList.get(i).valueText.getText();
				ruleStorageList.get(fieldName).add(rule);
			}
		}
		for(int z=0;z<ruleList.size();z++){
			if(ruleList.get(z).field.equals(fieldName)){
				if(ruleExists){
					ruleList.get(z).checkBox.setEnabled(true);
					ruleList.get(z).checkBox.setSelected(true);
					break;
				}else{
					ruleList.get(z).checkBox.setEnabled(false);
					ruleList.get(z).checkBox.setSelected(false);
					break;
				}
			}
		}
		
	}
	private static void initializeRulePanel(){
		internalRulePanel = new JPanel();
		internalRulePanel.setLayout(new GridBagLayout());
		scrollPane = new JScrollPane(internalRulePanel);
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.setPreferredSize(new Dimension(400,600));
		ruleList = new ArrayList<Rule>();
		
		//for each line on the scrollpane we will have 3 items,  
		for(int i =0;i<FieldInfo.getFieldNames().length;i++){
			Object[] fields = FieldInfo.getFieldNames();
			//Create a JLabel, JCheckbox, JButton for each field
			
			
			final Rule rule = new Rule((String)fields[i]);
			gbc.anchor = GridBagConstraints.LINE_START;
			gbc.gridx =0;
			gbc.gridy =i;
			internalRulePanel.add(rule.label,gbc);
			JCheckBox isOrigin = new JCheckBox("Origin");
			if(FieldInfo.getField((String)fields[i]).origin){
				isOrigin.setSelected(true);
			}else{
				isOrigin.setSelected(false);
			}
			isOrigin.setEnabled(false);

			gbc.gridx = 1;
			gbc.gridy = i;
			internalRulePanel.add(isOrigin,gbc);
			
			if(rule.checkBox.getListeners(ActionListener.class).length<1){
				rule.checkBox.addActionListener(new ActionListener(){
					public void actionPerformed(ActionEvent e){
						if(rule.checkBox.isSelected()){
							ruleActiveList.put(rule.field, true);
						}else if(!rule.checkBox.isSelected()){
							ruleActiveList.put(rule.field,false);
						}
					}
				});
			}
			gbc.gridx =2;
			gbc.gridy =i;
			internalRulePanel.add(rule.checkBox,gbc);
			gbc.gridx =3;
			gbc.gridy =i;
			internalRulePanel.add(rule.button,gbc);
			
			ChangeListener checkBoxListener = new ChangeListener(){
				@Override
				public void stateChanged(ChangeEvent arg0) {
					//Set all rules with this name to active
					if(!disableListener){
						ArrayList<Rule> temp = ruleStorageList.get(rule.field);
						if(temp != null){
							for(int z=0;z<temp.size();z++){
								temp.get(z).active = rule.checkBox.isSelected();
							}
						}
					}
				}
			};
			
			rule.checkBox.addChangeListener(checkBoxListener);
			ActionListener buttonListener = new ActionListener(){
				public void actionPerformed(ActionEvent e) {
					if(ruleStorageList.get(rule.field)==null||
						ruleStorageList.get(rule.field).size()<1){
						RuleEditor.showRuleEditor(rule.field);
					}else{
						//Populate rule editor with saved rules for this field
						RuleEditor.showRuleEditor(rule.field,ruleStorageList.get(rule.field));
					}
				}
			};
			rule.button.addActionListener(buttonListener);
			
			ruleList.add(rule);
		}
		gbc.gridx =0;
		gbc.gridy =0;
		rulePanel.add(scrollPane,gbc);
	}
	
	private static void attachListeners(){		
		deleteProfile.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(!deleteProfile.getText().equals("Duplicate Profile")){
					//Ask user to confirm choice
					int choice = JOptionPane.showConfirmDialog(null,"Are you sure you want to delete this profile?", "Delete Profile?" , JOptionPane.YES_NO_OPTION);
					if(choice == JOptionPane.OK_OPTION){
						boolean success = ProfileEditorGUI.deleteProfile(profileName);
						if(success){
							GUIFocusManager.remove();
						}
					}
				}else{
					String selection = (String)JOptionPane.showInputDialog(null, "Select profile to duplicate", "Duplicate Profile",
							JOptionPane.OK_CANCEL_OPTION, null, ProfileList.profileList.keySet().toArray(), "");
					if(selection!=null && selection.length()>0){
						//find profile to duplicate
						Profile profile = ProfileList.profileList.get(selection).clone();
						String input = JOptionPane.showInputDialog(null,"Enter new CNEE name");
						if(input!=null && input.length()>0){
							profile.profileName = input.toUpperCase();
							ProfileList.profileList.put(input.toUpperCase(), profile);
							ProfileEditorGUI.updateProfileList();
							GUIFocusManager.remove();
							ProfileEditor.openEditor(profile);
						}
					}
				}
			}
		});
		
		originCSSelector.addActionListener(new ActionListener(){	
			@Override
			public void actionPerformed(ActionEvent e) {
				SelectEmployeeDialog.open(true);
			}
		});
		destCSSelector.addActionListener(new ActionListener(){	
			@Override
			public void actionPerformed(ActionEvent e) {
				SelectEmployeeDialog.open(false);
			}
		});
		FocusListener emailListener = new FocusListener(){
			@Override
			public void focusGained(FocusEvent arg0) {
			}
			@Override
			public void focusLost(FocusEvent arg0) {
				if(emailText.getText()!=null && !emailText.getText().equals("")){
					//some text is in here, test for correctness
					if(!emailText.getText().contains("@")||!emailText.getText().contains(".")){
						JOptionPane.showMessageDialog(null, "Email has an invalid format!");
						emailText.setText("");
						emailText.requestFocus();
					}
				}
			}
		};
		emailText.addFocusListener(emailListener);
		
		FocusListener profileNameListener = new FocusListener(){
			@Override
			public void focusGained(FocusEvent arg0) {
			}
			@Override
			public void focusLost(FocusEvent arg0) {
				if(profileNameText.getText()!=null && !profileNameText.getText().equals("")){
					//some text is in here, test for correctness
					profileName = profileNameText.getText();
				}
			}
		};
		profileNameText.addFocusListener(profileNameListener);
		
		FocusListener cneeFocusListener = new FocusListener(){
			@Override
			public void focusGained(FocusEvent arg0) {
			}
			@Override
			public void focusLost(FocusEvent arg0) {
				if(cneeText.getText()!=null && !cneeText.getText().equals("")){
					//some text is in here, test for correctness
					cnee = cneeText.getText();
				}
			}
		};
		cneeText.addFocusListener(cneeFocusListener);
		
		
		FocusListener chargePerContainerListener = new FocusListener(){
	
			@Override
			public void focusGained(FocusEvent e) {
			}
			@Override
			public void focusLost(FocusEvent e) {
				try{
					Double.parseDouble(chargeText.getText());
				}catch(NumberFormatException e1){
					JOptionPane.showMessageDialog(null, "Charge per Container must be a number!");
					chargeText.setText("0.0");
					chargeText.requestFocus();
				}
			}
		};
		chargeText.addFocusListener(chargePerContainerListener);
		
		FocusListener termDayListener = new FocusListener(){
	
			@Override
			public void focusGained(FocusEvent e) {
			}
			@Override
			public void focusLost(FocusEvent e) {
				try{
					Integer.parseInt(termDayText.getText());
				}catch(NumberFormatException e1){
					JOptionPane.showMessageDialog(null, "Term must be an integer!");
					termDayText.setText("0");
					termDayText.requestFocus();
				}
			}
		};
		termDayText.addFocusListener(termDayListener);
		
		FocusListener billToListener = new FocusListener(){
	
			@Override
			public void focusGained(FocusEvent e) {
			}
			@Override
			public void focusLost(FocusEvent e) {
				if(billToText.getText()!=null && !billToText.getText().equals("")){
					//some text is in here, test for correctness
					billTo = billToText.getText();
				}
			}
		};
		billToText.addFocusListener(billToListener);
			ActionListener cancelListener = new ActionListener(){
				public void actionPerformed(ActionEvent e){
					//On cancel restore rule enabled booleans from storage
					if(profileReference!=null){
						Object[] keySet = ruleActiveList.keySet().toArray();
						for(int i=0;i<keySet.length;i++){
							for(int z=0;z<profileReference.ruleList.get(keySet[i]).size();z++){
								profileReference.ruleList.get(keySet[i]).get(z).active = ruleActiveList.get(keySet[i]);
							}
						}
					}
					GUIFocusManager.remove();
				}
			};
			cancel.addActionListener(cancelListener);
			ActionListener submitListener = new ActionListener(){
				public void actionPerformed(ActionEvent e){
					//Write to profileList and then save
					if(profileName==null||profileName.equals("")){
						JOptionPane.showMessageDialog(null, "Profile Name Cannot be Null!");
						profileNameText.requestFocus();
						return;
					}
					if(cnee==null || cnee.equals("")){
						JOptionPane.showMessageDialog(null, "CNEE Cannot be Null!");
						cneeText.requestFocus();
						return;
					}
//					if(originEmployeeMap==null || originEmployeeMap.size()<1){
//						JOptionPane.showMessageDialog(null, "Origin Office Cannot be Null!");
//						originCSSelector.requestFocus();
//						return;
//					}
//					if(destEmployeeMap==null || destEmployeeMap.size()<1){
//						JOptionPane.showMessageDialog(null, "Dest Office Cannot be Null!");
//						destCSSelector.requestFocus();
//						return;
//					}
	//				if(billTo == null || billTo.equals("")){
	//					JOptionPane.showMessageDialog(null, "Bill To Cannot be Null!");
	//					billToText.requestFocus();
	//					return;
	//				}
					
					Profile p = new Profile();
					p.profileName = profileName.toUpperCase();
					
					if(billToText.getText()!=null)
						p.billTo = billToText.getText().toUpperCase();
					else
						p.billTo = "";
					
					p.chargePerContainer = Double.parseDouble(chargeText.getText());
					if(cityText.getText()!=null)
						p.city = cityText.getText().toUpperCase();
					else
						p.city = "";
					
					p.cnee = cneeText.getText().toUpperCase();
					
					if(contactText.getText()!=null)
						p.contact = contactText.getText().toUpperCase();
					else
						p.contact = "";
					
					if(countryCombo.getSelectedIndex()>-1)
						p.country = (String) countryCombo.getSelectedItem();
					else
						p.country = "";
					
					p.daysAfter = (String) termFieldCombo.getSelectedItem();
					
					if(emailText.getText()!=null)
						p.email = emailText.getText().toUpperCase();
					else
						p.email = "";
					
					Object[] keyList = ruleActiveList.keySet().toArray();
					for(int i=0;i<keyList.length;i++){
						boolean b = ruleActiveList.get(keyList[i]);
						ArrayList<Rule> r = ruleStorageList.get(keyList[i]);
						for(int z=0;z<r.size();z++){
							r.get(z).active = b;
						}
					}
					p.ruleList = ruleStorageList;
					
					if(saleCombo.getSelectedIndex()>-1)
						p.saleHandler = (String) saleCombo.getSelectedItem();
					else
						p.saleHandler = "";
					
					if(stateText.getText()!=null)
						p.state = stateText.getText().toUpperCase();
					else
						p.state = "";
					
					if(streetText.getText()!=null)
						p.street = streetText.getText().toUpperCase();
					else
						p.street = "";
					
					if(telephoneText.getText()!=null)
						p.telephone = telephoneText.getText().toUpperCase();
					else
						p.telephone = "";
					
					p.term = Integer.parseInt(termDayText.getText());
					
					if(typeCombo.getSelectedIndex()>-1)
						p.type = (String) typeCombo.getSelectedItem();
					else
						p.type = "";
					
					if(zipText.getText()!=null)
						p.zip = zipText.getText();
					else
						p.zip = "";
					
					p.originEmployeeMap = originEmployeeMap;
					p.destEmployeeMap = destEmployeeMap;
					
					ProfileEditorGUI.profileList.put(profileName.toUpperCase(),p);
					//Clear some fields
					ruleStorageList = null;
					ProfileEditorGUI.updateProfileList(p);
					GUIFocusManager.remove();
				}
			};
			submit.addActionListener(submitListener);
	}
	public static void updateFields() {
		if(termFieldCombo == null){
			termFieldCombo = new JComboBox(FieldInfo.getNumericalFieldNames());
		}else{
			termFieldCombo.removeAllItems();
			for(int i=0;i<FieldInfo.getNumericalFieldNames().length;i++){
				termFieldCombo.addItem(FieldInfo.getNumericalFieldNames()[i]);
			}
		}
	}
	@SuppressWarnings("unchecked")
	public static void updateOriginEmployees(HashMap<String,ArrayList<String>> employeeMap){
		originEmployeeMap = (HashMap<String, ArrayList<String>>) employeeMap.clone();
		originCSCount.setText(Integer.toString(countEmployees(employeeMap)));
	}
	@SuppressWarnings("unchecked")
	public static void updateDestEmployees(HashMap<String,ArrayList<String>> employeeMap){
		destEmployeeMap = (HashMap<String, ArrayList<String>>) employeeMap.clone();
		destCSCount.setText(Integer.toString(countEmployees(employeeMap)));
	}
	public static HashMap<String,ArrayList<String>> getOriginEmployees(){
		return originEmployeeMap;
	}
	public static HashMap<String,ArrayList<String>> getDestEmployees(){
		return destEmployeeMap;
	}
	private static int countEmployees(HashMap<String,ArrayList<String>> employeeMap){

		int count = 0;
		if(employeeMap!=null){
			Object[] keyList = employeeMap.keySet().toArray();
			for(int i=0;i<keyList.length;i++){
				count += employeeMap.get(keyList[i]).size();
			}
		}
		return count;
	}
	public static void updateToAllRuleList(String fieldName,
			ArrayList<RuleGroup> ruleGroupList) {
		updateRuleList(fieldName,ruleGroupList);
		ArrayList<Rule> tmpStore = new ArrayList<Rule>();
		//clear all previously set rules
		for(int i=0;i<ruleGroupList.size();i++){
			
			//only add if rule exists
			if(ruleGroupList.get(i).subjectFieldCombo.getSelectedIndex()!=-1){
				
				Rule rule = new Rule(fieldName);
				rule.connector = (String) ruleGroupList.get(i).connectorCombo.getSelectedItem();
				rule.equality = (String) ruleGroupList.get(i).equalityCombo.getSelectedItem();
				rule.groupNo = (Integer) ruleGroupList.get(i).groupCombo.getSelectedItem();
				rule.subjectField = (String) ruleGroupList.get(i).subjectFieldCombo.getSelectedItem();
				rule.targetField = (String) ruleGroupList.get(i).targetFieldCombo.getSelectedItem();
				rule.value = ruleGroupList.get(i).valueText.getText();
				tmpStore.add(rule);
			}
		}
		
		//Add to all profiles
		Hashtable<String, Profile> profiles = ProfileList.profileList;
		Object[] profilesKeyList = profiles.keySet().toArray();
		for(int i = 0; i < profiles.size();i++){
			Profile currProfile = profiles.get(profilesKeyList[i]);
			currProfile.ruleList.put(fieldName,tmpStore);
		}
		
	}
}
